home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1996 September / macformat-041.iso / mac / Shareware City / Graphics / MacSPD / Sources / tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-30  |  5.7 KB  |  201 lines  |  [TEXT/MMCC]

  1. /*
  2.  * tree.c - Creates a tree using Aono & Kunii's generation method.
  3.  *      (See IEEE CG&A May 1984).  A square polygon is placed beneath the
  4.  *      tree to act as a field.  Seven light sources.
  5.  *
  6.  * Author:  Eric Haines, 3D/Eye, Inc.
  7.  *
  8.  * size_factor determines the number of objects output.
  9.  *      Total objects = 2**(SF+1)-1 cones and spheres + 1 square polygon.
  10.  *
  11.  *      size_factor     # spheres          # cones      # squares
  12.  *           1               3                 3             1
  13.  *           2               7                 7             1
  14.  *           3              15                15             1
  15.  *
  16.  *          11            4095              4095             1
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <math.h>
  21. #include <stdlib.h>     /* atoi */
  22. #include "def.h"
  23. #include "drv.h"        /* display_close() */
  24. #include "lib.h"
  25.  
  26. /* These may be read from the command line */
  27. static int size_factor       = 11;
  28. static int raytracer_format = OUTPUT_RT_DEFAULT;
  29. static int output_format    = OUTPUT_CURVES;
  30.  
  31.  
  32. /* the following affect the shape of the tree */
  33. #define BR_ANGLE_0              40.0
  34. #define BR_ANGLE_1              25.0
  35. #define BR_CONTR_0              0.65
  36. #define BR_CONTR_1              0.70
  37. #define BR_DIAMETER             0.67
  38. #define DIV_ANGLE               140.0
  39. #define WIDTH_HEIGHTH_RATIO     0.15
  40.  
  41. static  MATRIX  Rst_mx[2] ;
  42.  
  43. /* grow tree branches recursively */
  44. static void
  45. grow_tree(cur_mx, scale, depth)
  46.     MATRIX cur_mx;
  47.     double scale;
  48.     int depth;
  49. {
  50.     int i;
  51.     COORD3 vec;
  52.     COORD4 apex, base;
  53.     MATRIX new_mx;
  54.  
  55.     PLATFORM_MULTITASK();
  56.  
  57.     /* output branch */
  58.     SET_COORD3( vec, 0.0, 0.0, 0.0 ) ;
  59.     lib_transform_point( base, vec, cur_mx ) ;
  60.     base[W] = scale * WIDTH_HEIGHTH_RATIO ;
  61.  
  62.     SET_COORD3( vec, 0.0, 0.0, 1.0 ) ;
  63.     lib_transform_point( apex, vec, cur_mx ) ;
  64.     apex[W] = base[W] * BR_DIAMETER ;
  65.  
  66.     lib_output_cylcone( base, apex, output_format ) ;
  67.     lib_output_sphere( apex, output_format ) ;
  68.  
  69.     if ( depth > 0 ) {
  70.     --depth ;
  71.  
  72.     for ( i = 0 ; i < 2 ; ++i ) {
  73.         lib_matrix_multiply( new_mx, Rst_mx[i], cur_mx ) ;
  74.         grow_tree( new_mx, scale * BR_DIAMETER, depth ) ;
  75.     }
  76.     }
  77. }
  78.  
  79. /*
  80.  * Set up matrices for growth of each branch with respect to the
  81.  * parent branch, then grow each branch.
  82.  */
  83. static void
  84. create_tree()
  85. {
  86.     int i;
  87.     double branch_angle, branch_contraction, divergence;
  88.     MATRIX ident_mx, temp1_mx, temp2_mx, tempr_mx, tempst_mx;
  89.  
  90.     for ( i = 0 ; i < 2 ; ++i ) {
  91.     if ( i == 0 ) {
  92.         branch_angle = BR_ANGLE_0 ;
  93.         divergence = 90.0 ;
  94.         branch_contraction = BR_CONTR_0 ;
  95.     } else {
  96.         branch_angle = BR_ANGLE_1 ;
  97.         divergence = DIV_ANGLE + 90.0 ;
  98.         branch_contraction = BR_CONTR_1 ;
  99.     }
  100.  
  101.     /* rotate along X axis by branching angle */
  102.     lib_create_rotate_matrix( temp1_mx, X_AXIS, branch_angle*PI/180.0 ) ;
  103.  
  104.     /* rotate along Z axis by divergence angle */
  105.     lib_create_rotate_matrix( temp2_mx, Z_AXIS, divergence*PI/180.0 ) ;
  106.  
  107.     lib_matrix_multiply( tempr_mx, temp1_mx, temp2_mx ) ;
  108.  
  109.     /* include translation of branch, scaled */
  110.     lib_create_identity_matrix( tempst_mx ) ;
  111.     tempst_mx[0][0] = branch_contraction;
  112.     tempst_mx[1][1] = branch_contraction;
  113.     tempst_mx[2][2] = branch_contraction;
  114.     tempst_mx[3][2] = 1.0;
  115.  
  116.     /* concatenate */
  117.     lib_matrix_multiply( Rst_mx[i], tempr_mx, tempst_mx ) ;
  118.     }
  119.  
  120.     /* set up initial matrix */
  121.     lib_create_identity_matrix( ident_mx ) ;
  122.     grow_tree( ident_mx, 1.0, size_factor ) ;
  123. }
  124.  
  125. int
  126. main(argc,argv)
  127.     int argc;
  128.     char *argv[];
  129. {
  130.     COORD3 field[4];
  131.     COORD3 from, at, up;
  132.     COORD3 back_color, tree_color;
  133.     COORD4 light;
  134.     double lscale;
  135.  
  136.     PLATFORM_INIT(SPD_TREE);
  137.  
  138.     /* Start by defining which raytracer we will be using */
  139.     if ( lib_gen_get_opts( argc, argv,
  140.             &size_factor, &raytracer_format, &output_format ) ) {
  141.     return EXIT_FAIL;
  142.     }
  143.     if ( lib_open( raytracer_format, "Tree.out" ) ) {
  144.     return EXIT_FAIL;
  145.     }
  146.  
  147.     /* output background color - UNC sky blue */
  148.     /* NOTE: Do this BEFORE lib_output_viewpoint(), for display_init() */
  149.     SET_COORD3( back_color, 0.078, 0.361, 0.753 ) ;
  150.     lib_output_background_color( back_color ) ;
  151.  
  152.     /* output viewpoint */
  153.     SET_COORD3( from, 4.5, 0.4, 2.0 ) ;
  154.     SET_COORD3( at, 0.0, 0.0, 1.5 ) ;
  155.     SET_COORD3( up, 0.0, 0.0, 1.0 ) ;
  156.     lib_output_viewpoint(from, at, up, 45.0, 1.0, 1.0, 512, 512);
  157.  
  158.     /* output light sources */
  159.     if (raytracer_format == OUTPUT_NFF || raytracer_format == OUTPUT_RTRACE)
  160.     lscale = 1.0;
  161.     else
  162.     lscale = 1.0 / sqrt(7.0);
  163.  
  164.     /* output light source */
  165.     SET_COORD4( light, -5.0, 5.0, 50.0, lscale ) ;
  166.     lib_output_light( light ) ;
  167.     SET_COORD4( light, 30.0, -30.0, 30.0, lscale ) ;
  168.     lib_output_light( light ) ;
  169.     SET_COORD4( light, -40.0, -30.0, 20.0, lscale ) ;
  170.     lib_output_light( light ) ;
  171.     SET_COORD4( light, 10.0, 30.0, 40.0, lscale ) ;
  172.     lib_output_light( light ) ;
  173.     SET_COORD4( light, -30.0, 40.0, 10.0, lscale ) ;
  174.     lib_output_light( light ) ;
  175.     SET_COORD4( light, 50.0, 25.0, 20.0, lscale ) ;
  176.     lib_output_light( light ) ;
  177.     SET_COORD4( light, -10.0, -60.0, 30.0, lscale ) ;
  178.     lib_output_light( light ) ;
  179.  
  180.     /* output field polygon - green */
  181.     SET_COORD3( back_color, 0.2, 0.7, 0.2 ) ;
  182.     lib_output_color(NULL, back_color, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  183.     SET_COORD3( field[0],  50.0,  50.0, 0.0 ) ;
  184.     SET_COORD3( field[1], -50.0,  50.0, 0.0 ) ;
  185.     SET_COORD3( field[2], -50.0, -50.0, 0.0 ) ;
  186.     SET_COORD3( field[3],  50.0, -50.0, 0.0 ) ;
  187.     lib_output_polygon( 4, field ) ;
  188.  
  189.     /* set up tree color - brown */
  190.     SET_COORD3( tree_color, 0.55, 0.4, 0.2 ) ;
  191.     lib_output_color(NULL, tree_color, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0);
  192.  
  193.     /* create tree */
  194.     create_tree();
  195.  
  196.     lib_close();
  197.  
  198.     PLATFORM_SHUTDOWN();
  199.     return EXIT_SUCCESS;
  200. }
  201.